package com.logic.landseaserver.models.payment.util;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import com.logic.landseaserver.common.util.Base64;

/**
 * 
 *
 * 项目名称：system-server</br>
 * 类名称：ShiJiPosDesUtil</br>
 * 类描述：DES加密和解密.转为支持银石POS</br>
 * 创建人：Aaron</br>
 * 创建时间：2017年8月2日 下午1:55:19</br>
 * @version 1.0
 *
 */
public abstract class ShiJiPosDesUtil
{
    
    /** 安全密钥-和银石智能POS约定过的，不可更改 */
    private static final byte[] KEY_BYTE = "OFFLINE_POS@SIGN_KEY_10123456789-_.".getBytes();
    
    /**
     * 功能：加密 (UTF-8)
     * 
     * @author 宋立君
     * @date 2014年07月03日
     * @param source 源字符串
     * @param charSet 编码
     * @return String
     * @throws Exception 编码异常
     */
    public static String encrypt(String source)
        throws Exception
    {
        return encrypt(source, "UTF-8");
    }
    
    /**
     * 
     * 功能：解密 (UTF-8)
     * 
     * @author 宋立君
     * @date 2014年07月03日
     * @param encryptedData 被加密后的字符串
     * @return String
     * @throws UnsupportedEncodingException 编码异常
     */
    public static String decrypt(String encryptedData)
        throws Exception
    {
        return decrypt(encryptedData, "UTF-8");
    }
    
    /**
     * 功能：加密
     * 
     * @author 宋立君
     * @date 2014年07月03日
     * @param source 源字符串
     * @param charSet 编码
     * @return String
     * @throws Exception 异常
     */
    public static String encrypt(String source, String charSet)
        throws Exception
    {
        String encrypt = null;
        byte[] ret = encrypt(source.getBytes(charSet));
        encrypt = new String(Base64.encode(ret));
        return encrypt;
    }
    
    /**
     * 
     * 功能：解密
     * 
     * @author 宋立君
     * @date 2014年07月03日
     * @param encryptedData 被加密后的字符串
     * @param charSet 编码
     * @return String
     * @throws UnsupportedEncodingException 编码异常
     */
    public static String decrypt(String encryptedData, String charSet)
        throws Exception
    {
        String descryptedData = null;
        byte[] ret = descrypt(Base64.decode(encryptedData.toCharArray()));
        descryptedData = new String(ret, charSet);
        return descryptedData;
    }
    
    /**
     * 加密数据 用生成的密钥加密原始数据
     * 
     * @param primaryData 原始数据
     * @return byte[]
     * @author 宋立君
     * @date 2014年07月03日
     */
    private static byte[] encrypt(byte[] primaryData) throws Exception
    {
        /** DES算法要求有一个可信任的随机数源 */
        SecureRandom sr = new SecureRandom();
        
        /** 使用原始密钥数据创建DESKeySpec对象 */
        DESKeySpec dks = null;
        dks = new DESKeySpec(KEY_BYTE);
        
        /** 创建一个密钥工厂 */
        SecretKeyFactory keyFactory = null;
        keyFactory = SecretKeyFactory.getInstance("DES");
        
        /** 用密钥工厂把DESKeySpec转换成一个SecretKey对象 */
        SecretKey key = null;
        key = keyFactory.generateSecret(dks);
        
        /** Cipher对象实际完成加密操作 */
        Cipher cipher = null;
        cipher = Cipher.getInstance("DES");
        
        /** 用密钥初始化Cipher对象 */
        cipher.init(Cipher.ENCRYPT_MODE, key, sr);
        
        /** 正式执行加密操作 */
        byte encryptedData[] = null;
        encryptedData = cipher.doFinal(primaryData);
        
        /** 返回加密数据 */
        return encryptedData;
    }
    
    /**
     * 用密钥解密数据
     * 
     * @param encryptedData 加密后的数据
     * @return byte[]
     * @author 宋立君
     * @date 2014年07月03日
     */
    private static byte[] descrypt(byte[] encryptedData) throws Exception
    {
        
        /** DES算法要求有一个可信任的随机数源 */
        SecureRandom sr = new SecureRandom();
        
        /** 使用原始密钥数据创建DESKeySpec对象 */
        DESKeySpec dks = null;
        dks = new DESKeySpec(KEY_BYTE);
        
        /** 创建一个密钥工厂 */
        SecretKeyFactory keyFactory = null;
        keyFactory = SecretKeyFactory.getInstance("DES");
        
        /** 用密钥工厂把DESKeySpec转换成一个SecretKey对象 */
        SecretKey key = null;
        key = keyFactory.generateSecret(dks);
        
        /** Cipher对象实际完成加密操作 */
        Cipher cipher = null;
        cipher = Cipher.getInstance("DES");
        
        /** 用密钥初始化Cipher对象 */
        cipher.init(Cipher.DECRYPT_MODE, key, sr);
        
        /** 正式执行解密操作 */
        byte decryptedData[] = null;
        decryptedData = cipher.doFinal(encryptedData);
        
        return decryptedData;
    }
    
    /**
     * 取得安全密钥 此方法作废,因为每次key生成都不一样导致解密加密用的密钥都不一样， 从而导致Given final block not properly padded错误.
     * 
     * @return byte数组
     * @author 宋立君
     * @throws NoSuchAlgorithmException 
     * @date 2014年07月03日
     */
    public static byte[] getKey() throws NoSuchAlgorithmException
    {
        
        /** DES算法要求有一个可信任的随机数源 */
        SecureRandom sr = new SecureRandom();
        
        /** 为我们选择的DES算法生成一个密钥生成器对象 */
        KeyGenerator kg = null;
        kg = KeyGenerator.getInstance("DES");
        kg.init(sr);
        
        /** 生成密钥工具类 */
        SecretKey key = kg.generateKey();
        
        /** 生成密钥byte数组 */
        byte rawKeyData[] = key.getEncoded();
        
        return rawKeyData;
    }
    
/*    public static void main(String[] args) throws Exception
    {
        System.out.println(encrypt("1484"));
    }*/
}
